package com.yylending.las;

import android.app.Activity;
import android.app.Application;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.os.Build;
import android.support.v4.util.ArrayMap;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import cn.jpush.android.api.CustomPushNotificationBuilder;
import cn.jpush.android.api.JPushInterface;
import com.tencent.smtt.sdk.QbSdk;
import com.yyfax.common.CLog;
import com.yyfax.common.fingerprint.FingerprintIdentify;
import com.yyfax.common.fingerprint.base.BaseFingerprint;
import com.yyfax.common.tools.ManifestUtil;
import com.yyfax.common.tools.SystemTool;
import com.yyfax.infrastructure.base.BaseApplication;
import com.yyfax.infrastructure.eventbus.EventAgent;
import com.yyfax.infrastructure.mvp.IEvent;
import com.yyfax.infrastructure.mvp.ResponseCode;
import com.yyfax.infrastructure.network.NetworkHelper;
import com.yyfax.infrastructure.network.NetworkReceiver;
import com.yyfax.infrastructure.secure.RSA;
import com.yylending.las.authority.Account;
import com.yylending.las.authority.gestures.GesturesPresenter;
import com.yylending.las.common.location.LocationPresenter;
import com.yylending.las.common.location.LocationService;
import com.yylending.las.common.utils.preferenceutils.PreferenceConstants;
import com.yylending.las.common.utils.preferenceutils.PreferenceManager;
import com.yylending.las.common.widgets.lockpattern.ACache;
import com.yylending.las.common.widgets.lockpattern.LockPatternUtil;
import com.yylending.las.common.widgets.lockpattern.LockPatternView;

import java.util.List;

import static android.content.Context.INPUT_METHOD_SERVICE;
import static android.content.Context.TELEPHONY_SERVICE;

/**
 * Created by fuqiang on 2017/8/3.
 * Copyright  2017 www.yylending.com. All Rights Reserved.
 */

public class YJKD extends BaseApplication {
	public static final String TAG = "YJKD";

	public NetworkHelper networkHelper;
	public ACache mACache;

	public static String deviceId;

	public LocationService locationService;
	public NetworkReceiver mNetworkReceiver;

	public PreferenceManager mPreferenceManager;
	public FingerprintIdentify mFingerprintIdentify;

	private static volatile YJKD mInstance;

	public static YJKD getInstance() {
		if (mInstance == null) {
			synchronized (YJKD.class) {
				if (mInstance == null) {
					CLog.i(TAG, "initialize YJKD ...");
					mInstance = new YJKD();
				}
			}
		}
		return mInstance;
	}

	public void init(Application application) {
		mInstance = this;
		super.init(application);
		//print process name
		mPreferenceManager = new PreferenceManager(application);
		if (BuildConfig.DEBUG) {
			String processName = SystemTool.getCurrentProcessName(application);
			CLog.w(TAG, "YJKD.init(): ProcessName = " + processName);
		}
		//set singleton variable
		mNetworkReceiver = new NetworkReceiver();
		IntentFilter filter = new IntentFilter();
		filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
		application.registerReceiver(mNetworkReceiver, filter);

		readMetaData(application);
		//get mac id and app version code
		Global.getBaseInfo(application);

		//bank_card_scan_custom_view response code
		ResponseCode.CODE_SUCCESS = "000000";
		ResponseCode.CODE_SERVER_ERROR = "900001";
		ResponseCode.CODE_OPERATE_NONE = "900002";
		ResponseCode.CODE_PARAM_ERROR = "900003";
		ResponseCode.CODE_DECODE_FAIL = "900004";
		ResponseCode.CODE_LOGOUT = "800001";
		//use common parameters to initialization network tool
		ArrayMap<String, String> params = new ArrayMap<>();
		params.put("source", Global.SOURCE);
		params.put("version", Global.API_VERSION);
		params.put("device", Global.MAC_ID);
		params.put("channel", channel);//AnalyticsConfig.getChannel(application));
		params.put("aversion", Global.VERSION);
		//params.put("token", Global.LOGIN_TOKEN);
		//params.put("longitude", "");
		//params.put("latitude", "");
		networkHelper = NetworkHelper.getInstance(application, Global.BASE_URL, params);
		//other initialization logic
		initLocationService();
		readLocalUserInfo();
		mACache = ACache.get(application);

		saveTinkerNeedRestart(false);
		preInitX5WebCore();
		initJPush();
	}

	private void initJPush(){
		JPushInterface.setDebugMode(true); 	// 设置开启日志,发布时请关闭日志
		JPushInterface.init(mApplication);  // 初始化 JPush
		String rid = JPushInterface.getRegistrationID(mApplication);//获取注册ID
		CustomPushNotificationBuilder builder = new CustomPushNotificationBuilder(
				mApplication,
				R.layout.customer_notitfication_layout,
				R.id.icon, R.id.title, R.id.text);//指定定制的Notification Layout
		builder.statusBarDrawable = R.mipmap.ic_launcher;//指定最顶层状态栏小图标
		builder.layoutIconDrawable = R.mipmap.ic_launcher;//指定下拉状态栏时显示的通知图标
		builder.developerArg0 = "developerArg2";
		JPushInterface.setPushNotificationBuilder(2, builder);
	}

	private void preInitX5WebCore() {
		QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
			@Override
			public void onViewInitFinished(boolean arg0) {
				//x5內核初始化完成的回调，为true表示x5内核加载成功，否则表示x5内核加载失败，会自动切换到系统内核。
				CLog.i(TAG, " onViewInitFinished is " + arg0);
			}

			@Override
			public void onCoreInitFinished() {
				CLog.i(TAG, " onCoreInitFinished--");
			}
		};
		//x5内核初始化接口
		QbSdk.initX5Environment(mApplication,  cb);
	}

	public static void saveTinkerNeedRestart(boolean isNeedRestart) {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		pm.savePreference(PreferenceConstants.TINKER_NEED_RESTART, isNeedRestart);
	}

	public static void saveTinkerResult(String result) {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		pm.savePreference(PreferenceConstants.TINKER_RESULT, result);
	}

	public PreferenceManager getPreferenceManager() {
		return mPreferenceManager;
	}

	public void readMetaData(Context context) {
		Global.BASE_URL = ManifestUtil.readMetaDataFromApplication(context, "REMOTE_URL");
		com.yylending.remotevideo.Global.ANY_CHAT_APP_ID = ManifestUtil.readMetaDataFromApplication(context, "ANY_CHAT_APP_ID");
		com.yylending.remotevideo.Global.ANY_CHAT_QUEUE_ID = ManifestUtil.readIntMetaDataFromApplication(context, "ANY_CHAT_QUEUE_ID");
	}

	public void getDeviceId() {
		TelephonyManager tm = (TelephonyManager) mApplication.getSystemService(TELEPHONY_SERVICE);
		deviceId = tm.getDeviceId();
	}

	public void initLocationService() {
		LocationPresenter.clearSavedLocation();
		locationService = new LocationService(mApplication);
	}

	public void readLocalUserInfo() {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		Global.KEY_RSA = pm.getRSA();
		Global.KEY_AES = pm.getAES();
		Global.LOGIN_TOKEN = pm.getLoginToken();
		Global.LOGIN_ACCOUNT_NAME = pm.getLoginName();
		Global.LOGIN_USER_ID = pm.getLoginUserId();
		Global.USER_NAME = pm.getUserName();

		com.yylending.remotevideo.Global.TOKEN = Global.LOGIN_TOKEN;
	}

	public static boolean login() {
		return !TextUtils.isEmpty(Global.LOGIN_TOKEN);
	}

	public static void logout() {
		Global.LOGIN_TOKEN = "";
		Global.KEY_AES = "";
		Global.LOGIN_REAL_NAME = "";
		Global.LOGIN_USER_ID = "";
		Global.USER_NAME = "";
		Global.REGISTRATION_ID = "";
		loginFailed(false);

		com.yylending.remotevideo.Global.TOKEN = "";
	}

	public static void loginSuccess(Account rs, String name) {
		Global.KEY_AES = RSA.decryptByPublicKey(rs.aes, Global.KEY_RSA);
		Global.LOGIN_TOKEN = rs.token;
		com.yylending.remotevideo.Global.TOKEN = rs.token;
		Global.LOGIN_ACCOUNT_NAME = name;
		Global.LOGIN_USER_ID = rs.userId;
		Global.USER_NAME = rs.userName;

		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		if (!rs.userId.equals(pm.getLoginUserId())) {//清除手势密码
			clearGesture(false);
			YJKD.getInstance().setFingerprintOpen(false);
		}
		pm.savePreference(PreferenceConstants.KEY_RSA, Global.KEY_RSA);
		pm.savePreference(PreferenceConstants.KEY_AES, Global.KEY_AES);
		pm.savePreference(PreferenceConstants.KEY_LOGIN_NAME, Global.LOGIN_ACCOUNT_NAME);
		pm.savePreference(PreferenceConstants.SP_KEY_LOGIN_TOKEN, rs.token);
		pm.savePreference(PreferenceConstants.SP_KEY_LOGIN_USERID, rs.userId);
		pm.savePreference(PreferenceConstants.SP_KEY_USER_NAME, rs.userName);
	}

	public static void loginFailed(boolean decodeFailed) {
		PreferenceManager pm = YJKD.getInstance().getPreferenceManager();
		if (decodeFailed) {//解密失败时清空RSA密钥
			Global.KEY_RSA = "";
			pm.savePreference(PreferenceConstants.SP_KEY_LOGIN_USERID, "");
		}
		pm.savePreference(PreferenceConstants.KEY_RSA, "");
		pm.savePreference(PreferenceConstants.KEY_AES, "");
		pm.savePreference(PreferenceConstants.SP_KEY_LOGIN_TOKEN, "");
		pm.savePreference(PreferenceConstants.SP_KEY_USER_NAME, "");
	}

	public static void clearGesture(boolean logout) {
		GesturesPresenter.resetGestureCount();
		GesturesPresenter.writeStatus(false);
		YJKD.getInstance().removeChosenPattern();
		if (logout) {
			EventAgent.postSticky(new IEvent.UnLoginEvent(IEvent.CODE_UNLOGIN));
		}
	}

	public static boolean isRealName() {
		return !TextUtils.isEmpty(Global.LOGIN_REAL_NAME);
	}

	/**
	 * 隐藏输入法(Activity)
	 */
	public static void hideInputWindow(Activity activity) {
		try {
			View view = activity.getCurrentFocus();
			if (view != null) {
				// 设置输入法输入完成时对话框自动隐藏
				((InputMethodManager) app().getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
			}
		} catch (Exception e) {
		}
	}

	/**
	 * 显示输入法(Activity)
	 */
	public static void showInputWindow() {
		try {
			((InputMethodManager) app().getSystemService(INPUT_METHOD_SERVICE)).toggleSoftInput(InputMethodManager.SHOW_FORCED, InputMethodManager.HIDE_IMPLICIT_ONLY);
		} catch (Exception e) {
		}
	}

	/**
	 * 隐藏输入法(Dialog)
	 */
	public static void hideInputWindow(Dialog dialog) {
		try {
			View view = dialog.getCurrentFocus();
			if (view != null) {
				// 设置输入法输入完成时对话框自动隐藏
				((InputMethodManager) app().getSystemService(INPUT_METHOD_SERVICE)).hideSoftInputFromWindow(view.getWindowToken(), 0);
			}
		} catch (Exception e) {
		}
	}

	public boolean checkChosenPattern(List<LockPatternView.Cell> cells) {
		byte[] oldPattern = mACache.getAsBinary(Constants.GESTURE_PASSWORD);
		return LockPatternUtil.checkPattern(cells, oldPattern);
	}

	public boolean saveChosenPattern(List<LockPatternView.Cell> cells) {
		byte[] bytes = LockPatternUtil.patternToHash(cells);
		boolean result = mACache.put(Constants.GESTURE_PASSWORD, bytes);
		if(!result){
			ACache.clearInstanceMap(mApplication);
			mACache = ACache.get(mApplication);
		}
		return result;
	}

	public void removeChosenPattern() {
		mACache.remove(Constants.GESTURE_PASSWORD);
	}

	public boolean hadLockPattern() {
		byte[] pattern = mACache.getAsBinary(Constants.GESTURE_PASSWORD);
		return pattern != null;
	}

	public static void tel(Context context, String phone) {
		Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phone));
		context.startActivity(intent);
	}

	/**
	 * 初始化指纹验证类
	 */
	public void initFingerprint() {
		mFingerprintIdentify = new FingerprintIdentify(mApplication, new BaseFingerprint.FingerprintIdentifyExceptionListener() {
			@Override
			public void onCatchException(Throwable exception) {
				CLog.i(TAG, "Exception：" + exception.getLocalizedMessage());
			}
		});
	}

	/**
	 * Android M以上、有指纹模块、设置了指纹
	 */
	public boolean hasFingerprint() {
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
			return false;
		}
		initFingerprint();
		boolean result = mFingerprintIdentify.isHardwareEnable() && mFingerprintIdentify.isRegisteredFingerprint() && mFingerprintIdentify.isFingerprintEnable();
		mFingerprintIdentify.cancelIdentify();
		return result;
	}

	public boolean isFingerprintAvailable() {
		if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
			return false;
		}
		initFingerprint();
		boolean result = mFingerprintIdentify.isHardwareEnable();
		mFingerprintIdentify.cancelIdentify();
		return result;
	}

	public boolean isFingerprintOpen() {
		return getPreferenceManager().isEnableFingerprint();
	}

	public void setFingerprintOpen(boolean open) {
		getPreferenceManager().savePreference(PreferenceConstants.SP_KEY_FINGERPRINT_TOGGLE, open);
	}
}
